package ro.msg.quiz.view;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.DefaultTableModel;

import ro.msg.quiz.controller.Controller;
import ro.msg.quiz.repository.Question;
import ro.msg.quiz.repository.Quiz;

/**
 * Create the main frame.
 * 
 * @author Adorjan
 */
public class MainWindow extends JFrame {
	private static int NOT_ASSIGNED = -1;
	private static int QUIZ_MODE = 0;
	private static int QUESTION_MODE = 1;
	private static int COLUMN_ID = 3; // the column that contains the ids
	private JPanel contentPane;
	private final JTable tableQuestion = new JTable();
	private final JTable tableQuiz = new JTable();
	private final JScrollPane paneQuestion = new JScrollPane();
	private final JScrollPane paneQuiz = new JScrollPane();
	private final JButton btnAdd = new JButton("Add");
	private final JButton btnEdit = new JButton("Edit");
	private final JButton btnDelete = new JButton("Delete");
	private final JButton btnImportTxt = new JButton("Import TXT");
	private final JButton btnExportTxt = new JButton("Export TXT");
	private final JButton btnImportXml = new JButton("Import XML");
	private final JButton btnExportXml = new JButton("Export XML");
	private final JButton btnImportSql = new JButton("Import SQL");
	private final JButton btnExportSql = new JButton("Export SQL");
	private final JButton btnShow = new JButton("Show");
	private final JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
	private int state; // 0 if quiz, 1 if question
	private final String dirpath = ".";
	private Controller ctrl;

	/**
	 * The frame's constructor
	 * 
	 * @author Adorjan
	 */
	public MainWindow(Controller controller) {
		this.ctrl = controller;
		setResizable(false);
		setTitle("Questionnaire");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 507, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		/**
		 * Add button's action listener
		 */
		btnAdd.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (state == QUIZ_MODE) {
					try {
						AddNewQuiz dialogQuiz = AddNewQuiz.getInstance(ctrl);
						dialogQuiz
								.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
						dialogQuiz.setVisible(true);
						dialogQuiz.addWindowListener(new WindowAdapter() {
							@Override
							public void windowClosed(WindowEvent arg0) {
								updateQuizTable();
								AddNewQuiz.reset();
							}
						});
					} catch (Exception e) {
						e.printStackTrace();
					}
				} else // state == QUESTION_MODE
				{
					try {
						AddNewQuestion dialogQuestion = AddNewQuestion
								.getInstance(ctrl);
						dialogQuestion
								.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
						dialogQuestion.setVisible(true);
						dialogQuestion.addWindowListener(new WindowAdapter() {

							@Override
							public void windowClosed(WindowEvent arg0) {
								updateQuestionTable();
								AddNewQuestion.reset();

							}
						});
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		});
		btnAdd.setBounds(25, 34, 72, 23);
		contentPane.add(btnAdd);

		/**
		 * Edit button's action listener
		 */
		btnEdit.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (state == QUIZ_MODE) {
					if (tableQuiz.getSelectedRow() != NOT_ASSIGNED) {
						try {
							int rowNum = tableQuiz.getSelectedRow();
							AddNewQuiz dialogQuiz = AddNewQuiz.getInstance(
									ctrl, (Integer) tableQuiz.getModel()
											.getValueAt(rowNum, COLUMN_ID));
							dialogQuiz
									.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
							dialogQuiz.setVisible(true);
							dialogQuiz.addWindowListener(new WindowAdapter() {

								@Override
								public void windowClosed(WindowEvent arg0) {
									updateQuizTable();
									AddNewQuiz.reset();
								}
							});
						} catch (Exception e) {
							e.printStackTrace();
						}
					} else
						JOptionPane.showMessageDialog(null,
								"Please select a quiz!", "Oops!",
								JOptionPane.WARNING_MESSAGE);
				} else // state == QUESTION_MODE
				{
					if (tableQuestion.getSelectedRow() != NOT_ASSIGNED) {
						try {
							int rowNum = tableQuestion.getSelectedRow();
							AddNewQuestion dialogQuestion = AddNewQuestion
									.getInstance(
											ctrl,
											(Integer) tableQuestion.getModel()
													.getValueAt(rowNum,
															COLUMN_ID));
							dialogQuestion
									.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
							dialogQuestion.setVisible(true);
							dialogQuestion
									.addWindowListener(new WindowAdapter() {

										@Override
										public void windowClosed(
												WindowEvent arg0) {
											updateQuestionTable();
											AddNewQuestion.reset();
										}
									});
						} catch (Exception e) {
							e.printStackTrace();
						}
					} else
						JOptionPane.showMessageDialog(null,
								"Please select a question!", "Oops!",
								JOptionPane.WARNING_MESSAGE);
				}

			}
		});
		btnEdit.setBounds(117, 34, 72, 23);
		contentPane.add(btnEdit);

		/**
		 * Delete button's action listener
		 */
		btnDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (state == QUIZ_MODE) {
					if (tableQuiz.getSelectedRow() != NOT_ASSIGNED) {
						int dialogResult = JOptionPane.showConfirmDialog(null,
								"Are you sure you want to delete this quiz?",
								"Warning", JOptionPane.YES_NO_OPTION);
						if (dialogResult == JOptionPane.YES_OPTION) {
							int rowNum = tableQuiz.getSelectedRow();
							ctrl.removeQuiz((Integer) tableQuiz.getModel()
									.getValueAt(rowNum, COLUMN_ID));
							updateQuizTable();
						}
					} else
						JOptionPane.showMessageDialog(null,
								"Please select a quiz!", "Oops!",
								JOptionPane.WARNING_MESSAGE);
				} else // state == QUESTION_MODE
				{
					if (tableQuestion.getSelectedRow() != NOT_ASSIGNED) {
						int dialogResult = JOptionPane
								.showConfirmDialog(
										null,
										"Are you sure you want to delete this question?",
										"Warning", JOptionPane.YES_NO_OPTION);
						if (dialogResult == JOptionPane.YES_OPTION) {
							int rowNum = tableQuestion.getSelectedRow();
							ctrl.removeQuestion((Integer) tableQuestion
									.getModel().getValueAt(rowNum, COLUMN_ID));
							updateQuestionTable();
						}
					} else
						JOptionPane.showMessageDialog(null,
								"Please select a question!", "Oops!",
								JOptionPane.WARNING_MESSAGE);
				}
			}
		});
		btnDelete.setBounds(212, 34, 72, 23);
		contentPane.add(btnDelete);

		btnImportTxt.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnImportTxt.setBounds(402, 34, 89, 23);
		contentPane.add(btnImportTxt);
		/**
		 * Import txt button's action listener
		 */
		btnImportTxt.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				String path = "";
				JFileChooser openFile = new JFileChooser(dirpath);
				openFile.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				int okay = openFile.showOpenDialog(null);
				if (okay == JFileChooser.APPROVE_OPTION) {
					path = openFile.getSelectedFile().getAbsolutePath()
							.toString();
					importEvent(path);
				}
			}
		});

		btnShow.setBounds(307, 34, 72, 23);
		contentPane.add(btnShow);
		/**
		 * Show button's action listener
		 */
		btnShow.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				int rowNum = tableQuestion.getSelectedRow();
				if (rowNum != NOT_ASSIGNED) {
					Question tempQuestion = ctrl
							.getModel()
							.getQuestionRepo()
							.getQuestion(
									(Integer) tableQuestion.getModel()
											.getValueAt(rowNum, COLUMN_ID));
					StringBuffer buffer = new StringBuffer();
					buffer.append("ID: ");
					buffer.append(tempQuestion.getId());
					buffer.append("\n Text: ");
					buffer.append(tempQuestion.getText());
					buffer.append("\n Answer(s): ");
					for (String option : tempQuestion.getOptions()) {
						buffer.append(option);
						buffer.append(" ");
					}
					JOptionPane.showMessageDialog(null, buffer.toString(),
							"Question details", JOptionPane.PLAIN_MESSAGE);
				} else
					JOptionPane.showMessageDialog(null,
							"Please select a question!", "Oops!",
							JOptionPane.WARNING_MESSAGE);

			}
		});

		/**
		 * tabbed pane's change listener
		 */
		tabbedPane.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent arg0) {
				if (tabbedPane.getTitleAt(tabbedPane.getSelectedIndex())
						.equals("Quizes")) {
					state = QUIZ_MODE;
					btnShow.setVisible(false);
				} else {
					btnShow.setVisible(true);
					state = QUESTION_MODE;
				}
			}
		});
		tabbedPane.setBounds(39, 74, 337, 186);
		contentPane.add(tabbedPane);

		tabbedPane.addTab("Questions", null, paneQuestion, null);

		tableQuestion.setModel(new DefaultTableModel(new Object[][] {},
				new String[] { "Question", "Type", "Last edited", "ID" }) {
			Class[] columnTypes = new Class[] { String.class, String.class,
					String.class, Integer.class };

			@Override
			public Class getColumnClass(int columnIndex) {
				return columnTypes[columnIndex];
			}

			boolean[] columnEditables = new boolean[] { false, false, false,
					false };

			@Override
			public boolean isCellEditable(int row, int column) {
				return columnEditables[column];
			}
		});
		tableQuestion.getColumnModel().getColumn(0).setPreferredWidth(88);
		tableQuestion.getColumnModel().getColumn(1).setPreferredWidth(80);
		tableQuestion.getColumnModel().getColumn(2).setPreferredWidth(93);
		tableQuestion.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tableQuestion.removeColumn(tableQuestion.getColumnModel().getColumn(
				COLUMN_ID));
		paneQuestion.setViewportView(tableQuestion);

		tabbedPane.addTab("Quizes", null, paneQuiz, null);
		tableQuiz.setModel(new DefaultTableModel(new Object[][] {},
				new String[] { "Quiz", "Number of questions", "Last edited",
						"ID" }) {
			Class[] columnTypes = new Class[] { String.class, Integer.class,
					String.class, Integer.class };

			@Override
			public Class getColumnClass(int columnIndex) {
				return columnTypes[columnIndex];
			}

			boolean[] columnEditables = new boolean[] { false, false, false,
					false };

			@Override
			public boolean isCellEditable(int row, int column) {
				return columnEditables[column];
			}
		});
		tableQuiz.getColumnModel().getColumn(0).setPreferredWidth(97);
		tableQuiz.getColumnModel().getColumn(1).setPreferredWidth(109);
		tableQuiz.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tableQuiz.removeColumn(tableQuiz.getColumnModel().getColumn(COLUMN_ID));

		paneQuiz.setViewportView(tableQuiz);

		/**
		 * Export sql button's action listener
		 */
		btnExportSql.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				ctrl.getDatabase().ExportSqlDatabase(ctrl.getModel());
			}
		});
		btnExportSql.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnExportSql.setBounds(402, 185, 89, 23);
		contentPane.add(btnExportSql);

		/**
		 * Export xml button's action listener
		 */
		btnExportXml.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(null, "Comming soon!", "Wait",
						JOptionPane.WARNING_MESSAGE);
			}
		});
		btnExportXml.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnExportXml.setBounds(402, 219, 89, 23);
		contentPane.add(btnExportXml);

		btnExportTxt.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnExportTxt.setBounds(402, 151, 89, 23);
		contentPane.add(btnExportTxt);

		/**
		 * Import sql button's action listener
		 */
		btnImportSql.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				ctrl.setModel(ctrl.getDatabase().ImportSqlDatabase());
				updateQuestionTable();
				updateQuizTable();
			}
		});
		btnImportSql.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnImportSql.setBounds(402, 68, 89, 23);
		contentPane.add(btnImportSql);

		/**
		 * Import xml button's action listener
		 */
		btnImportXml.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(null, "Comming soon!", "Wait",
						JOptionPane.WARNING_MESSAGE);
			}
		});
		btnImportXml.setFont(new Font("Tahoma", Font.PLAIN, 11));
		btnImportXml.setBounds(402, 102, 89, 23);
		contentPane.add(btnImportXml);

		updateQuestionTable();
		updateQuizTable();
		exportTxt();

	}

	/**
	 * refreshes the questionTable - shows the datas introduced in the
	 * repository
	 * 
	 * @author Adorjan
	 */
	public void updateQuestionTable() {
		DefaultTableModel dtm = (DefaultTableModel) tableQuestion.getModel();
		if (dtm.getRowCount() > 0) {
			for (int i = dtm.getRowCount() - 1; i > -1; i--) {
				dtm.removeRow(i);
			}
		}
		for (Question question : ctrl.getQuestionList()) {
			String qType;
			switch (question.getType()) {
			case 1:
				qType = "Single choice";
				break;
			case 2:
				qType = "Multiple choice";
				break;
			case 3:
				qType = "Text";
				break;
			default:
				qType = "Unknown";
				break;
			}
			dtm.addRow(new Object[] { question.getText(), qType,
					question.getLastEdited(), question.getId() });
		}
	}

	/**
	 * refreshes the quizTable - shows the datas introduced in the repository
	 * 
	 * @author Adorjan
	 */
	public void updateQuizTable() {
		DefaultTableModel dtm = (DefaultTableModel) tableQuiz.getModel();
		if (dtm.getRowCount() > 0) {
			for (int i = dtm.getRowCount() - 1; i > -1; i--) {
				dtm.removeRow(i);
			}
		}
		for (Quiz quiz : ctrl.getQuizList()) {
			dtm.addRow(new Object[] { quiz.getQuizName(),
					ctrl.getNoOfQuestions(quiz.getId()), quiz.getLastEdited(),
					quiz.getId() });
		}
	}

	/**
	 * listener on the Export Txt button
	 */
	public void exportTxt() {
		btnExportTxt.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				try {
					String path = "";
					JFileChooser j = new JFileChooser(dirpath);
					j.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
					int okay = j.showSaveDialog(null);
					if (okay == JFileChooser.APPROVE_OPTION) {
						path = j.getSelectedFile().getAbsolutePath().toString();
						ctrl.ExportTxt(path);
					}
				} catch (Exception e) {
					JOptionPane.showMessageDialog(null,
							"Error while exporting txt");
				}
				/*
				 * finally { JOptionPane.showMessageDialog(null,
				 * "The export txt is made"); }
				 */

			}
		});
	}

	/**
	 * This method handles the import from txt file
	 * 
	 * @param path
	 */
	private void importEvent(String path) {
		ctrl.clearRepositories();
		ctrl.readFromFileQuestion(path);
		ctrl.readFromFileQuiz(path);
		ctrl.readFromFileQuizQuestion(path);
		updateQuestionTable();
		updateQuizTable();
	}
}
